import * as THREE from 'three';
// console.log(THREE);


// 引入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 引入动画库
import  gsap from 'gsap';
import { Camera } from 'three';

//  1.创建场景
const scene = new THREE.Scene()



//  2.创建并添加相机
/* PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number )
fov — 摄像机视锥体垂直视野角度
aspect — 摄像机视锥体长宽比
near — 摄像机视锥体近端面
far — 摄像机视锥体远端面 */
const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)  //创建相机
/* position.set ( x : Float, y : Float, z : Float ) : this
设置该向量的x、y 和 z 分量。 */
camera.position.set(0,0,10) //设置相机位置
scene.add(camera)//在场景中添加相机



//  3. 在场景中创建并添加物体
/* BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)
width — X轴上面的宽度，默认值为1。
height — Y轴上面的高度，默认值为1。
depth — Z轴上面的深度，默认值为1。*/
const cubGeometry = new THREE.BoxGeometry( 1, 1, 1 );// 创建几何立方体
const cubMaterial = new THREE.MeshBasicMaterial({color: 0x00ff00} );// 添加材质
const cube = new THREE.Mesh( cubGeometry, cubMaterial );// 将几何体和材质组合为物体

//  物体的缩放
// cube.scale.set(3,2,1);//指物体在X,Y,Z轴上的缩放倍数
//  物体的旋转 ———— 欧拉角描述一个旋转变换，通过指定轴顺序和其各个轴向上的指定旋转角度来旋转一个物体。
// cube.rotation.set(Math.PI/4,0,0,'XYZ')//物体沿X轴旋转90度

scene.add( cube );//在场景中添加物体



//  4.设置渲染器并渲染场景
const renderer = new THREE.WebGL1Renderer() //初始化渲染器
renderer.setSize(window.innerWidth,window.innerHeight)  //设置渲染的尺寸大小
document.body.appendChild(renderer.domElement);// 将webgl渲染的内容添加到body
// renderer.render(scene,camera) // 使用渲染器，通过相机将场景渲染进来 


// 5.添加辅助坐标轴
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );

// 6.添加控制器-轨道控制器 可以使得相机围绕目标进行轨道运动  通过不断地重新渲染来实现移动视角的效果
const controls = new OrbitControls(camera,renderer.domElement);
// 10.设置控制器阻尼 更真实  需要在每一帧重新生成时调用controls.update();
controls.enableDamping = true;


// 设置时钟
const clock = new THREE.Clock();

//  9.gsap 补间动画  ——  无需再手动计算时间做动画了  内置API自动生成  并能通过丰富的参数和回调进行控制
let animate_line = gsap.to(cube.position,{ 
    x: 5 ,                  //轴对象与动画值
    duration: 5 ,           //持续时间
    ease: "power1.inOut" ,  //速度
    repeat:-1 ,             //重复次数
    yoyo:true ,             //往返运动
    delay:2 ,               //延迟动画开始时间 
    onComplete:()=>{        //动画完成的回调函数

    },
    onStart:()=>{        //动画开始的回调函数

    }
});
let animate_rotat = gsap.to(cube.rotation,{ x: Math.PI*2 , duration: 5 , repeat:-1 , ease: "power1.inOut"});

window.addEventListener("click",()=>{//单击屏幕暂停
    animate_line.isActive()?animate_line.pause():animate_line.resume()
    animate_rotat.isActive()?animate_rotat.pause():animate_rotat.resume()
})
window.addEventListener("dblclick",()=>{//双击屏幕全屏/取消全屏
    document.fullscreenElement?document.exitFullscreen():renderer.domElement.requestFullscreen()
})

function render(){//递归实现每一帧的重新渲染
    //  8.制作动画  ——  时间动画原理(通过每一帧的生成时间为基准来渲染动画  clock函数或render自带时间参数)  较简单 略...  
    renderer.render(scene,camera)
    requestAnimationFrame(render);
    controls.update();
}
render();

// 11.监听画面变化渲染画面  
window.addEventListener('resize',()=>{
    camera.aspect = window.innerWidth/window.innerHeight//更新相机
    camera.updateProjectionMatrix();//更新相机投影矩阵
    renderer.setSize(window.innerWidth,window.innerHeight)//更新渲染器尺寸大小
    renderer.setPixelRatio(window.devicePixelRatio)//设置渲染器像素比————就是缩放比
})